package org.wattdepot.cli.commands;

import java.util.List;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.property.jaxb.Property;
import org.wattdepot.resource.source.jaxb.Source;
import org.wattdepot.resource.source.jaxb.SubSources;
import org.wattdepot.resource.source.summary.jaxb.SourceSummary;

/**
 * This class contains a command that prints out the summary of the given source by the user in the
 * CommandLineInterface.
 * 
 * Modified by David Mau.
 * @author Nathaniel Ashe
 * 
 */
public class ListSummaryCommand implements WattDepotCliCommand {
  // Default client-server connection to use unless given one.
  private WattDepotClient client = new WattDepotClient(debug);
  
  /**
   * This constructor makes sure that the client really is connected to the server.
   * 
   * @param anotherClient Specifies if the user wants to use another WattDepot server
   * other than the default simulation one.
   */
  public ListSummaryCommand( String anotherClient ) {
    // If another client is provided
    if ( anotherClient != null ) {
      client = new WattDepotClient( anotherClient );
    }
    
    // Stops right away if we cannot contact server.
    if (!client.isHealthy()) {
      System.out.println("Failed to connect to " + client.getWattDepotUri());
      return;
    }
    // Indicate successful connection
    //System.out.println("Connected to " + client.getWattDepotUri());
  }

  /**
   * This method returns a String that contains the summary of the given source by the user. The
   * String is ready to print in a table format
   * 
   * Created by Nathaniel Ashe
   * 
   * @param args A list of arguments for this command.
   * @return A string.
   */
  public String doCommand(List<String> args) {
    boolean first = true;
    String output = "";
    StringBuffer outputSubSources = new StringBuffer();
    StringBuffer outputProperties = new StringBuffer();
    outputSubSources.append( "" );
    outputProperties.append( "" );

    if (args.size() > 1) {
      output = tooManyArguments;
      output = output.concat(cr);
      return output;
    }
    if (args.size() < 1) {
      output = missingArguments;
      output = output.concat(cr);
      return output;
    }

    Source source;

    try {
      source = client.getSource(args.get(0));
      SubSources subsources = source.getSubSources();
      SourceSummary summary = client.getSourceSummary(args.get(0));

      // If there are no subsources, don't collect them
      if ( subsources != null) {
        // Collect subsources
        for (int x = 0; x < subsources.getHref().size(); x++) {
          if ( first ) {
            outputSubSources.append(subsources.getHref().get(x).substring(
                subsources.getHref().get(x).lastIndexOf("/") + 1));
            first = false;
          }
          outputSubSources.append( ", " + subsources.getHref().get(x).substring(
              subsources.getHref().get(x).lastIndexOf("/") + 1));
        }
      }

      // If there are no properties, don't collect them
      if ( source.getProperties() != null ) {
        List<Property> properties = 
            source.getProperties().getProperty();
        for ( Property property : properties ) {
            outputProperties.append( String.format("(%s: %s) ", property.getKey(), 
                property.getValue()) );     
        }
      }

      output += "Subsources: " + outputSubSources + "\n";
      output += "Description: " + source.getDescription() + "\n";
      output +=
          "Owner: " + source.getOwner().substring(source.getOwner().lastIndexOf("/") + 1) + "\n";
      output += "Location: " + source.getLocation() + "\n";
      output += "Coordinates: " + source.getCoordinates() + "\n";
      output += "Properties: " + outputProperties + "\n";
      output += "Earliest data: " + summary.getFirstSensorData() + "\n";
      output += "Latest data: " + summary.getLastSensorData() + "\n";
      output += "Total data points: " + summary.getTotalSensorDatas() + "\n";
      return output;
    }
    catch (NotAuthorizedException e) {
      output = notAuthorized;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (ResourceNotFoundException e) {
      output = resourceNotFound;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (BadXmlException e) {
      output = badXml;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (MiscClientException e) {
      output = miscClient;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
  }
}